﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using TheMovieDB;
using System.IO;
using System.Threading.Tasks;
using TMS;

namespace TMDB
{
    public class FileListReadyInfoArgs : EventArgs 
    {
        public List<TMSMovie> MovieList { private set; get; }
        public FileListReadyInfoArgs(List<TMSMovie> movielist) 
        {
            MovieList = movielist;
        }
    }

    public class OnMovieInfoReadyEventArgs : EventArgs
    {
        public int TotalFiles { get; private set; }
        public int CurrentFile { get; private set; }
        public OnMovieInfoReadyEventArgs(int totalFiles,int currentFile)
        {
            TotalFiles = totalFiles;
            CurrentFile = currentFile;
        }
    }

    [Serializable]
    public class TMSFolderInfo
    {
        public string DirectoryPath { get; set; }
        public string Name { set; get; }

        public string ProxyAddress { get; set; }
        public string FileExtensions { get; set; }
        public string Status { set; get; }

        public event EventHandler OnMovieAdded;
        public event EventHandler OnMovieInfoRefresh;
        public event EventHandler<OnMovieInfoReadyEventArgs> OnMovieInfoReady;

        private int current = 0;
        private int progress = 0;

        public bool Processed {  set; get; }
        [NonSerialized]
        private bool isProcessing = false;

        public int TotalFiles 
        {
            get 
            {
                return total;
            }
            set 
            {
                total = value;
            }
        }

        public int FileProgress
        {
            get 
            {
                return current;
            }
            set 
            {
                current = value;
            }
        }

        public int Progress
        {
            get 
            {
                return progress;
            }
            set 
            {
                progress = value;
            }
        }
        private int total = 0;

        List<TMSMovie> movies = new List<TMSMovie>();

        public List<TMSMovie> Movies 
        {
            get 
            {
                return movies;
            }
            set 
            {
                movies = value;
            }
        
        }

        public void LoadDirectoryInfo() 
        {
            if (isProcessing)
                throw new ApplicationException("Still loading directory info");

            Status = "Processing Request";

            ThreadPool.QueueUserWorkItem(o =>
            {
                isProcessing = true;
                total = 0;
                current = 0;
                Status = "Loading File List ...";
                List<String> files = new List<string>();
                files.AddRange(GetFiles(DirectoryPath, FileExtensions.Replace(",", " , ").Trim().Split(',').ToList(), SearchOption.AllDirectories));

                total = files.Count;

                TmdbAPI tmdbAPI = new TmdbAPI("958508f40a0cb941b485cdd1e15afdda");
                tmdbAPI.ProxyAddress = ProxyAddress;
                Status = "Loading Media Info ...";
                Parallel.ForEach(files, file =>
                {
                    var tmpmove = movies.Find(myfile => myfile.Filename == file);
                    
                    if (tmpmove == null)
                    {
                        TMSMovie mov = new TMSMovie(this.Name, file, ProxyAddress);
                        mov.OnInfoReady += new EventHandler(mov_OnInfoReady);
                        mov.OnInfoRefreshed += new EventHandler(mov_OnInfoRefreshed);
                        if (OnMovieAdded != null)
                            OnMovieAdded(mov, null);

                        mov.LoadMovieInfo();
                        movies.Add(mov);
                    }
                    else 
                    {
                        if (tmpmove.MovieInfoState == TMDBMovieInfoState.InfoFound)
                        {
                            //if (OnMovieAdded != null)
                            //    OnMovieAdded(tmpmove, null);
                            tmpmove.OnInfoRefreshed += new EventHandler(tmpmove_OnInfoRefreshed);
                            this.mov_OnInfoReady(tmpmove, null);
                        }
                        else 
                        {
                            tmpmove.OnInfoReady += new EventHandler(mov_OnInfoReady);
                            tmpmove.OnInfoRefreshed += new EventHandler(tmpmove_OnInfoRefreshed);
                            //if (OnMovieAdded != null)
                            //    OnMovieAdded(tmpmove, null);
                            tmpmove.LoadMovieInfo();
                        }
                    }
                });
                tmdbAPI = null;
            });
        }

        void tmpmove_OnInfoRefreshed(object sender, EventArgs e)
        {
            if (OnMovieInfoRefresh != null)
                OnMovieInfoRefresh(sender, e);
        }

        void mov_OnInfoRefreshed(object sender, EventArgs e)
        {
            if (OnMovieInfoRefresh != null)
                OnMovieInfoRefresh(sender, e);
        }

        private List<string> GetFiles(string path, List<string> searchPatterns, SearchOption searchOption)
        {
            var result = searchPatterns.SelectMany(x => Directory.GetFiles(path, x, searchOption));
            return result.ToList();
        }

        void mov_OnInfoReady(object sender, EventArgs e)
        {
            current++;
            Status = "Processing File : " + current.ToString() + "/" + total.ToString();
            
            progress = Convert.ToInt32(Math.Min(((decimal)current / (decimal)total) * 100, 100)); 

            if (current == total)
            {
                Status = "Completed";
                isProcessing = false;
            }

            if (OnMovieInfoReady != null)
                OnMovieInfoReady(sender, new OnMovieInfoReadyEventArgs(total,current));
        }
    }
}
